﻿//Copyright 2008 Kristian Gundry And Rune Juhl-Petersen
//This file is part of Plain.

//Plain is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//any later version.

//Plain is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU Lesser General Public License for more details.

//You should have received a copy of the GNU Lesser General Public License
//along with Plain.  If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Plain.Search;

namespace Plain.Data{
    public static class IDaoExtensions
    {
        #region Methods

        /// <summary>
        /// Persists the entity.
        /// </summary>
        /// <remarks>
        /// If <see cref="IDao"/> cannot be found, it will throw an <see cref="Exception"/>
        /// </remarks>
        /// <param name="entity">the entity to persist</param>
        /// <returns>True/false</returns>
        public static bool Save(this IBusinessEntity entity){
            IDaoFactory factory = PlainApplication.Config.DaoFactory;

            Type dft = factory.GetType();
            MethodInfo[] methods = dft.GetMethods();
            MethodInfo g = null;
            object value = null;

            foreach (MethodInfo m in methods) {
                if (m.Name == "GetDao" && m.IsGenericMethod) {
                    g = m.MakeGenericMethod(entity.GetType(), entity.GetType().GetProperty("Id").PropertyType);
                    break;
                }
            }
            
            if (g != null) {
                object Dao;
                Dao = g.Invoke(factory, null);

                Type dt = Dao.GetType();
                MethodInfo dm = dt.GetMethod("Save");

                value = dm.Invoke(Dao, new object[] { entity });

                return true;// (bool)value;// default(TT);
            } else return false;            
        }

        /// <summary>
        /// Deletes the entity from persistance media.
        /// </summary>
        /// <remarks>
        /// If <see cref="IDao"/> cannot be found, it will throw an <see cref="Exception"/>
        /// </remarks>
        /// <param name="entity">The entity to delete</param>
        /// <returns>True/False</returns>
        public static bool Delete(this IBusinessEntity entity) {
            IDaoFactory factory = PlainApplication.Config.DaoFactory;

            Type dft = factory.GetType();
            MethodInfo[] methods = dft.GetMethods();
            MethodInfo g = null;
            object value = null;

            foreach (MethodInfo m in methods) {
                if (m.Name == "GetDao" && m.IsGenericMethod) {
                    g = m.MakeGenericMethod(entity.GetType(), entity.GetType().GetProperty("Id").PropertyType);
                    break;
                }
            }
            
            if (g != null){
                object Dao = g.Invoke(factory, null);

            Type dt = Dao.GetType();
            MethodInfo dm = dt.GetMethod("Delete");

            value = dm.Invoke(Dao, new object[] { entity });

            return (bool)value;// default(TT);
            } else return false;
        }
        
        #endregion
    }
    public static class SearchExtension { 
       public static IList<T> Search<T,TT>(this ISearchableDao<T,TT> dao, Criteria crit) where T:IBusinessEntity<TT>{
            return dao.Search(crit, null, 0, 0, "");
        }
    	
    	public static IList<T> Search<T,TT>(this ISearchableDao<T,TT> dao, Criteria crit,string order) where T:IBusinessEntity<TT>{
            return dao.Search(crit, null, 0, 0, order);
        }
		public static IList<T> Search<T,TT>(this ISearchableDao<T,TT> dao, Criteria crit, IDictionary<string, object> dic) where T:IBusinessEntity<TT>{
            return dao.Search(crit, dic, 0, 0, "");
        }
    	public static IList<T> Search<T,TT>(this ISearchableDao<T,TT> dao, Criteria crit, IDictionary<string, object> dic,string order) where T:IBusinessEntity<TT>{
            return dao.Search(crit, dic, 0, 0, order);
        }
        public static int GetCount<T, TT>(this ISearchableDao<T, TT> dao, Criteria crit) where T : IBusinessEntity<TT> {
            return dao.GetCount(crit, null);
        }
   }
}
